package gene.core;

import gene.core.sound.SoundPlayer;
import java.applet.Applet;
import java.io.IOException;
import java.io.InputStream;
//#if plataform == me
//# import javax.microedition.lcdui.Graphics;
//# import javax.microedition.lcdui.Image;
//# import javax.microedition.lcdui.game.GameCanvas;
//#else
import java.awt.Color;
import java.awt.DisplayMode;
import java.awt.Graphics2D;
import java.awt.GraphicsDevice;
import java.awt.GraphicsEnvironment;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.awt.image.BufferStrategy;
import javax.swing.JPanel;
//import core.util.Screen;
import java.awt.Image;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.InputStream;
import java.net.URL;
import javax.imageio.ImageIO;
import javax.swing.JFrame;
//#endif

/**
 *
 * @author vinicius
 */
public class Core 
        //#if plataform = me 
        //# extends GameCanvas
        //#else 
	  extends Applet
        implements Runnable{

    public static Image        _image        = null;
    public static  InputStream   _inputStream  = null;
    public static  String        _string       = null;
    public static  byte[]        _byteArray    = null;
    //#if plataform == me
    //# public static  Graphics      graphics      = null;
    //#else
    public static JFrame container;
    public static JPanel panel;
    public static BufferStrategy strategy;
    public static Graphics2D graphics;//, tmp;
    public static GraphicsDevice device;
    //#endif

    public static  Scene         _screen       = null;
    private static Core          instace       = null;
    public static  GraphicDevice graphicDevice = null;
    public static SoundPlayer filesoundPlayer  = new SoundPlayer();
    //public static TonePlayer  toneSoundPlayer = null;
    private static int fps = 28;
    public int lastFps = 0;
    public int fpsCont = 0;
    public static int color_background = 0x000000;
    public static int FRAME_SKIP = 2;
    public static int LOOP_TIME = 0;
    public static int GLOBAL_TICKS = 0;
    public static int W = 0;
    public static int H = 0;
    /*cellphone key code*/
    public static int KEYCODE_ID_UP = -1;
    public static int KEYCODE_ID_DOWN = -2;
    public static int KEYCODE_ID_LEFT = -3;
    public static int KEYCODE_ID_RIGHT = -4;
    public static int KEYCODE_ID_FIRE = -5;
    public static int KEYCODE_ID_SOFTKEY_LEFT = -6;
    public static int KEYCODE_ID_SOFTKEY_RIGHT = -7;
    /**/
    public final static int STATE_ID_RUNNING = 1;
    public final static int STATE_ID_PAUSED = 2;
    public static int sleep_time = 1000 / fps;
    public static int _KEYS_PRESSED = 0;
    public static boolean GLOBAL_RUNNING = true;
    public static boolean ENABLE_PLAYER_CONTROL = true;
    public static boolean GLOBAL_FULLSCREEN = true;
    public static boolean fire_pressed = false;
    public static boolean bt_pressed_up = false;
    public static boolean bt_pressed_down = false;
    public static boolean bt_pressed_left = false;
    public static boolean bt_pressed_right = false;
    public static boolean bt_pressed_softkey_left = false;
    public static boolean bt_pressed_softkey_right = false;
       public static boolean bt_pressed_1 = false;
    public static boolean bt_pressed_2 = false;
    public static boolean bt_pressed_3 = false;
    public static boolean bt_pressed_4 = false;
    public static boolean bt_pressed_5 = false;
    public static boolean bt_pressed_6 = false;
    public static boolean bt_pressed_7 = false;
    public static boolean bt_pressed_8 = false;
    public static boolean bt_pressed_9 = false;
    public static boolean bt_pressed_0 = false;
    public static boolean bt_pressed_star = false;
    public static boolean bt_pressed_pound = false;
    public static boolean fullScreen = false;
    public int coreState = 0;
    public int orientation = -1;
    public int index = 0;
    public int start = 0;
    private Thread thread = null;

    //private Component list[] = null;

    /**
     * Get the <code>Core</core> reference .
     * @return the class instance
     */
    public static Core getInstance() {
        return instace;
    }

    /**
     * Initialize the engine creating one global reference
     * @param w width of device screen
     * @param h heigth of device screen
     * @param fullscreen 
     */
    public static Core InitEngine(int w, int h, boolean fullscreen) {
        if (instace == null) {
            instace = new Core(fullscreen, w, h);
        }
    return instace;
    }

    /**
     * Verify if <code>Core</core> has been initialized
     * @return
     */
    public static boolean isInitialized() {
        return instace != null;
    }

    private Core(boolean fullscreen, int w, int h) {

        System.out.print("w "+w+" h"+h);

        //#if plataform == me
        //# super(false);
        //# setFullScreenMode(true);
        //#else
        setFullScreenMode(fullscreen);
        setScreen(w, h, fullscreen);
        panel.addKeyListener(new KeyAdapter() {

            @Override
            public void keyPressed(KeyEvent ev) {Core.keyPressed(ev);}

            @Override
            public void keyReleased(KeyEvent ev) {Core.keyReleased(ev);}
        });
        panel.requestFocusInWindow();
        panel.setFocusTraversalKeysEnabled(false);
        //#endif
        GLOBAL_TICKS = 1;

        W = w;
        H = h;
        System.out.print("*** w "+w+" h"+h);
        
        graphicDevice = new GraphicDevice(w,h);//.getInstance();
        //instace = this;
        coreState = STATE_ID_RUNNING;
        thread = new Thread(this);
        thread.start();

    }

    //#if plataform == me
    //# /**
    //#  *
    //#  * @return
    //#  */
    //# public Graphics getCoreGraphics() {
    //#     return graphics;
    //# }
    //#endif
    
    /**
     * get the sleep milliseconds to system sleep after each loop
     * @return <code> sleep_time</code>

    public static int getSleepTime() {
    return sleep_time;
    }*/
    public int getW() {
        return W;
    }

    public int getH() {
        return H;
    }

    public void setW(int w) {
        W = w;
    }

    public void setH(int h) {
        H = h;
    }

    /**
     * Update the system Time
     */
    public void updateTime() {
        start =(int) System.currentTimeMillis() - start;
        ++GLOBAL_TICKS;
    }

    //#if platafor != me
    /**
     * changes the video mode to fullscreen or not and resize the screen size
     * @param w  new screen width
     * @param h new screen height
     * @param fullscreen
     */
    private void setFullScreenMode(boolean fullscreen) {
        fullScreen = fullscreen;
    }
    //#endif

        /**
     *
     * @param tmx
     * @param tmy
     */
    private void setScreen(int w,int h, boolean fullscreen) {

        container = new JFrame("GENE Desktop ");
        GraphicsEnvironment environment = GraphicsEnvironment.getLocalGraphicsEnvironment();
        device = environment.getDefaultScreenDevice();
        /*int _w = w;
        int _h = h;

        if (w < 320){
            _w = 320;
        }

        if (h < 240){
          _h = 240;
        }
*/
        

        //System.out.println("w "+W+" h"+H);


        //W = tmx;
        //H = tmy;

        if (fullScreen) {
            container.setUndecorated(true);
        }
        
        panel = (JPanel) container.getContentPane();
        panel.setLayout(null);
        panel.setSize(w,h);
        container.setSize(w,h);
        container.setBounds(0, 0,w,h);
        container.setIgnoreRepaint(true);

        container.setResizable(false);
        container.setVisible(true);
        
        container.createBufferStrategy(2);

        container.setDefaultCloseOperation(container.EXIT_ON_CLOSE);
        
        strategy = container.getBufferStrategy();
        ///fullScreen=false;

        if (fullScreen) {
            device.setFullScreenWindow(container);
            container = (JFrame) device.getFullScreenWindow();
            device.setDisplayMode(new DisplayMode(w,h, 16, 60));
            strategy = device.getFullScreenWindow().getBufferStrategy();
        }

        graphics  = (Graphics2D) strategy.getDrawGraphics();
    }


    /**
     * Force the system close, clear and exit.
     */
    public void exit() {//forca a saida
        GLOBAL_RUNNING = false;

        clearMem();
        System.gc();
        System.exit(1);

    }

    
    protected void keyPressed(int keyCode) {
        //_KEYS_PRESSED = keyCode;

       //System.out.println("********");
    
        //switch (keyCode) {
            if(keyCode == KEYCODE_ID_UP){
                bt_pressed_up = true;
            }
            if(keyCode == KEYCODE_ID_DOWN) {
                bt_pressed_down = true;
            }
            if(keyCode == KEYCODE_ID_LEFT) {
                bt_pressed_left = true;
            }
            if(keyCode == KEYCODE_ID_RIGHT) {
                bt_pressed_right = true;
            }
            if(keyCode == KEYCODE_ID_FIRE) {
                fire_pressed = true;
            }
            if(keyCode == KEYCODE_ID_SOFTKEY_LEFT) {
                bt_pressed_softkey_left = true;
            }
            if(keyCode == KEYCODE_ID_SOFTKEY_RIGHT) {
                bt_pressed_softkey_right = true;
            }

        //}

    }


    protected void KeyReleased(int keyCode) {
        //System.out.println("********");
    
//        _KEYS_PRESSED = keyCode;

        if(keyCode == KEYCODE_ID_UP) {
                bt_pressed_up = false;
            }
          if(keyCode == KEYCODE_ID_DOWN){
                bt_pressed_down = false;
            }
           if(keyCode == KEYCODE_ID_LEFT) {
                bt_pressed_left = false;
            }
            if(keyCode == KEYCODE_ID_RIGHT) {
                bt_pressed_right = false;
            }
            if(keyCode == KEYCODE_ID_FIRE) {
                fire_pressed = false;
            }
            if(keyCode == KEYCODE_ID_SOFTKEY_LEFT) {
                bt_pressed_softkey_left = false;
            }
            if(keyCode == KEYCODE_ID_SOFTKEY_RIGHT) {
                bt_pressed_softkey_right = false;
            }
        //}

     }


    public static void keyPressed(KeyEvent e) {
        if (e.getID() == KeyEvent.KEY_PRESSED ) {
            //pressed = true;
            int code = e.getKeyCode();

            if (code == KeyEvent.VK_DOWN) {
                bt_pressed_down = true;
            }
            if (code == KeyEvent.VK_UP) {
                bt_pressed_up = true;
            }
            if (code == KeyEvent.VK_LEFT) {
                bt_pressed_left = true;
            }
            if (code == KeyEvent.VK_RIGHT) {
                bt_pressed_right = true;
            }
            if (code == KeyEvent.VK_ENTER) {
                bt_pressed_right = true;
            }
            if (code == KeyEvent.VK_SPACE) {
                fire_pressed = true;
            }
            if (code == KeyEvent.VK_ESCAPE) {
                bt_pressed_left = true;
            }
if (code == KeyEvent.VK_0) {
                bt_pressed_0 = true;
            }
            if (code == KeyEvent.VK_1) {
                bt_pressed_1 = true;
            }
            if (code == KeyEvent.VK_2) {
                bt_pressed_2 = true;
            }
            if (code == KeyEvent.VK_3) {
                bt_pressed_3 = true;
            }
            if (code == KeyEvent.VK_4) {
                bt_pressed_4 = true;
            }
            if (code == KeyEvent.VK_5) {
                bt_pressed_5 = true;
            }
            if (code == KeyEvent.VK_6) {
                bt_pressed_6 = true;
            }
if (code == KeyEvent.VK_7) {
                bt_pressed_7 = true;
            }
            if (code == KeyEvent.VK_8) {
                bt_pressed_8 = true;
            }
            if (code == KeyEvent.VK_9) {
                bt_pressed_9 = true;
            }
            if (code == KeyEvent.VK_ALT) {
                bt_pressed_pound = true;
            }
            if (code == KeyEvent.VK_CONTROL) {
                bt_pressed_star = true;
            }
            
        }

    // throw new UnsupportedOperationException("Not supported yet.");
    }

    public static void keyReleased(KeyEvent e) {
        //throw new UnsupportedOperationException("Not supported yet.");
        if (e.getID() == KeyEvent.KEY_RELEASED ) {
            //pressed = false;
            int code = e.getKeyCode();
if (code == KeyEvent.VK_DOWN) {
                bt_pressed_down = false;
            }
            if (code == KeyEvent.VK_UP) {
                bt_pressed_up = false;
            }
            if (code == KeyEvent.VK_LEFT) {
                bt_pressed_left = false;
            }
            if (code == KeyEvent.VK_RIGHT) {
                bt_pressed_right = false;
            }
            if (code == KeyEvent.VK_ENTER) {
                bt_pressed_right = false;
            }
            if (code == KeyEvent.VK_SPACE) {
                fire_pressed = false;
            }
            if (code == KeyEvent.VK_ESCAPE) {
                bt_pressed_left = false;
            }
if (code == KeyEvent.VK_0) {
                bt_pressed_0 = false;
            }
            if (code == KeyEvent.VK_1) {
                bt_pressed_1 = false;
            }
            if (code == KeyEvent.VK_2) {
                bt_pressed_2 = false;
            }
            if (code == KeyEvent.VK_3) {
                bt_pressed_3 = false;
            }
            if (code == KeyEvent.VK_4) {
                bt_pressed_4 = false;
            }
            if (code == KeyEvent.VK_5) {
                bt_pressed_5 = false;
            }
            if (code == KeyEvent.VK_6) {
                bt_pressed_6 = false;
            }
if (code == KeyEvent.VK_7) {
                bt_pressed_7 = false;
            }
            if (code == KeyEvent.VK_8) {
                bt_pressed_8 = false;
            }
            if (code == KeyEvent.VK_9) {
                bt_pressed_9 = false;
            }
            if (code == KeyEvent.VK_ALT) {
                bt_pressed_pound = false;
            }
            if (code == KeyEvent.VK_CONTROL) {
                bt_pressed_star = false;
            }

        }
    }


    /**
     * Method to update the keyboard state
     * @param keyCode
     */
    public boolean isKeyPressed(int keyCode) {
        if ((_KEYS_PRESSED & keyCode) != 0) {
            return true;
        }
        return false;
    }

    /**
     *Clear the memory removing all local allocated objects and references,
     */
    public void clearMem() {

        if(_screen!=null){
            _screen.destroy();
            _screen.destroyScene();
            _screen = null;
        }
        if (filesoundPlayer != null) {
            filesoundPlayer.stopMusic();
            filesoundPlayer.destroy();
            filesoundPlayer = null;
        }
        /*if (toneSoundPlayer != null) {
            //toneSoundPlayer.stopMusic();
            global.filesoundPlayer = null;
        }*/
        _screen.clear();
        _screen.destroy();
       // _image = null;
        _inputStream = null;
        _string = null;
        _byteArray = null;
        instace = null;
    }

    /**
     * Method to control the main loop
     */
    public void run() {

        while (STATE_ID_RUNNING == coreState) {

            graphicDevice.clear_Screen();

            updateTime();
            /*if(_image != null){
               graphicDevice.buffer(_image, 0, 0);
            }*/

            if (_screen != null) {
                _screen.update();
                _screen.paint();
            }else{
                //#if platafor==me
                //# graphics.setColor(0x00ffffff);
                //# graphics.drawString("screen null pointer", 0,40, 0);
                //#endif
            }
            graphicDevice.paint();
        }

        //clearMem();
    }

    /**
     * Pause the game
     */
    public void pause() {
        _screen.pause();
    }

    /**
     * Resume the game
     */
    public void resume() {
        _screen.resume();
    }

    /**
     * initialize the inner instances of Core
     */
    public void setScreen(Scene screen) {
       /*if (screen == null) {
            new Exception("Core Screen null pointer exception");
        }*/
        _screen = screen;
        coreState = STATE_ID_RUNNING;
        //new SplashScreen();
    }

    /*
     * Return the current system time
     * @return <code>GLOBAL_TIME</code>
     *
    public long getTime() {
        return GLOBAL_TIME;
    }*/

    /**
     * Reset to 0 the current global time
     */
    public void stopTime() {
        GLOBAL_TICKS = 0;
    }

    /**
     * get the current screen on <code>Code</code>
     * @return current screen;
     */
    public Scene getCurrentScreen() {
        return _screen;
    }

    /**
     *
     * @param r
     * @param g
     * @param b
     */
    public void setBackgroundColor(int color) {
        color_background = color;
    }

    /**
     *  Make the system sleeps int time millisecs
     * @param time
     */
    public static void sleep(int time) {
        try {
            Thread.sleep(time);
        } catch (Exception e) {
            //e.printStackTrace();
        }
    }

    /**
     * Loads target file
     * @param file <b>String name of file</b>
     * @return InputStream from loaded file
     */
    public static InputStream loadFile(String file) {
        try {
            return file.getClass().getResourceAsStream(file);
        } catch (Exception e) {
            //e.printStackTrace();
        }
        file = null;
        return null;
    }

    /////////////////////////// sessao graficos /////////////////////////////
    /*bufferiza no segundo passo;
    public void buffer(Component compo) {
        compo.draw();
    }

    public void draw_Pixel(int x, int y, int color) {
        graphics.setColor(color);
        graphics.drawLine(x, y, ++x, ++y);
    }
 int i=0;
    public void clear_Screen() {
        //i+=0x00040000;
        graphics.setColor(0x00000000);
        //graphics.setColor(i);
        graphics.fillRect(0, 0, W, H);
    }

    **
     * Save images on buffer to show him on <code>paint()</code>
     * @param x postition X on device screen
     * @param y postition Y on device screen
     *
    public void buffer(Image img, int x, int y) {

        if (img != null && (GLOBAL_TICKS % FRAME_SKIP) == 0) {
            //se estiver setado para rotacionar , recria todas as imagens re-orientando-as
        /*    if (orientation > 0) {
                graphics.drawImage(Image.createImage(img, 0, 0, img.getWidth(), img.getHeight(), orientation), y, x, 0);
            } else {*/
                /*graphics.drawImage(img, x, y, 0);
            //}
        }
        img = null;
    }

    **
     * clear the device screen and show all elements of current <code>Screen</code>
     
    public void /*flush*/ /*paint() {
      if(GLOBAL_TICKS % FRAME_SKIP == 0){

        int time = (int) (System.currentTimeMillis() - start)>>3;

        graphics.setColor(0X00ffffff);

        graphics.drawString("start "+(time),0, 20,0);

        graphics.drawString("fps "+lastFps+" "+((time % 100)==0),0,0,0);

        if(time % 100 == 0){
                graphics.setColor(0);
                 lastFps = fpsCont;
                  fpsCont = 0;
                  //start = 0;
           }


                flushGraphics();
                fpsCont++;

        }

                
        if ((GLOBAL_TICKS % 20) == 0) {
            System.gc();
        }
        
        sync();//list = null;
    }

    **
     * Load image from file
     * @param file
     * @return
     *
    public static Image loadImage(String file) {
        _image = null;
        try {
            _image = Image.createImage(file.getClass().getResourceAsStream(file));
            file = null;
        } catch (IOException ex) {
            //if mode_debug
            ex.printStackTrace();
        //endif
        }
        return _image;

    }

    /*
     * Get the rbg background color array;
     * @return
     *
    public int getRGB_Background() {
        return color_background;
    }
*/
    public void sync() {
        sleep(sleep_time);
    }

    //#if plataform == me
    public void flush(){
    //# flushGraphics();
    }
    //#endif

    /**
     * Load image from file
     * @param file
     * @return
     */
    public static Image loadImage(String file) {
        _image = null;
        System.out.println("\n"+file);
        //URL url = file.getClass().getClassLoader().getResource("./src/"+file);
        try {

            File f = new File("./src/"+file);
            BufferedImage b = ImageIO.read(f);

            //Image img =ImageIO.read(new File("./src/"+file));
            //graphics.drawImage(img, 0, 0, null);
            
            //_image = ImageIO.read(url);//file.getClass().getResourceAsStream("./src/"+file)) ;
            //Image.createImage(file.getClass().getResourceAsStream(file));
            //file = null;
            _image = b.getSubimage(0,0,b.getWidth(),b.getHeight());
        } catch (IOException ex) {
            //if mode_debug
            ex.printStackTrace();
        //endif
        }
        return _image;

    }

}
